home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Networking / OTPAPSampleServer / StringUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  15.2 KB  |  771 lines  |  [TEXT/CWIE]

  1. /*
  2. **    Apple Macintosh Developer Technical Support
  3. **
  4. **    Collection of String Utilities for DTS Sample code
  5. **
  6. **    File:        StringUtils.c
  7. **
  8. **    Copyright © 1988-1993 Apple Computer, Inc.
  9. **    All rights reserved.
  10. */
  11.  
  12. /* You may incorporate this sample code into your applications without
  13. ** restriction, though the sample code has been provided "AS IS" and the
  14. ** responsibility for its operation is 100% yours.  However, what you are
  15. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  16. ** after having made changes. If you're going to re-distribute the source,
  17. ** we require that you make it clear in the source that the code was
  18. ** descended from Apple Sample Code, but that you've made changes. */
  19.  
  20. #ifndef __MEMORY__
  21. #include <Memory.h>
  22. #endif
  23.  
  24. #ifndef __STRINGUTILS__
  25. #include "StringUtils.h"
  26. #endif
  27.  
  28.  
  29. /* These functions should be linked into whatever segment holds main().  This will
  30. ** guarantee that the functions will always be in memory when called.  It is important
  31. ** that they are in memory, because if a pointer is passed in that points into an
  32. ** unlocked handle, the mere fact that the code needs to get loaded may cause the
  33. ** handle that is pointed into to move.  If you stick to these string functions,
  34. ** you will not have to worry about the handle moving when the string function is
  35. ** called.  If you have your own string functions, and you wish the same safety
  36. ** factor, link the string handling code into the same segment as main(), as you
  37. ** do with these string functions. */
  38.  
  39. static short    gBase;
  40. static Boolean    gHandleChars;
  41.  
  42.  
  43.  
  44. /*****************************************************************************/
  45. /*****************************************************************************/
  46.  
  47.  
  48.  
  49. /* Return the length of the c-string.  (Same as strlen, but this function isn't
  50. ** part of the string library.  The entire library may be more than you wish to
  51. ** link into the code segment that holds main, so this (and other) standard
  52. ** library function has been duplicated here. */
  53.  
  54. short    clen(char *cptr)
  55. {
  56.     short    i;
  57.  
  58.     for (i = 0; cptr[i]; ++i) {};
  59.     return(i);
  60. }
  61.  
  62.  
  63.  
  64. /*****************************************************************************/
  65.  
  66.  
  67.  
  68. /* Catenate two c-strings. */
  69.  
  70. char    *ccat(char *s1, char *s2)
  71. {
  72.     ccpy(s1 + clen(s1), s2);
  73.     return(s1);
  74. }
  75.  
  76.  
  77.  
  78. /*****************************************************************************/
  79.  
  80.  
  81.  
  82. /* Copy a c-string. */
  83.  
  84. char    *ccpy(char *s1, char *s2)
  85. {
  86.     char    *c1, *c2;
  87.  
  88.     c1 = s1;
  89.     c2 = s2;
  90.     while ((*c1++ = *c2++) != 0) {};
  91.     return(s1);
  92. }
  93.  
  94.  
  95.  
  96. /*****************************************************************************/
  97.  
  98.  
  99.  
  100. /* Compare two pascal-strings. */
  101.  
  102. short    pcmp(StringPtr s1, StringPtr s2)
  103. {
  104.     short    i, len, j;
  105.  
  106.     if ((len = s1[0]) > s2[0]) len = s2[0];
  107.  
  108.     for (i = 1; i <= len; ++i) {
  109.         j = ((unsigned short)s1[i] - (unsigned short)s2[i]);
  110.         if (j) return(j);
  111.     }
  112.  
  113.     return(s1[0] - s2[0]);
  114. }
  115.  
  116.  
  117.  
  118. /*****************************************************************************/
  119.  
  120.  
  121.  
  122. /* Catenate two pascal-strings. */
  123.  
  124. void    pcat(StringPtr d, StringPtr s)
  125. {
  126.     short    i, j;
  127.  
  128.     if (((j = s[0]) + d[0]) > 255)
  129.         j = 255 - d[0];
  130.             /* Limit dest string to 255. */
  131.  
  132.     for (i = 0; i < j;) d[++d[0]] = s[++i];
  133. }
  134.  
  135.  
  136.  
  137. /*****************************************************************************/
  138.  
  139.  
  140.  
  141. /* Copy a pascal-string. */
  142.  
  143. void    pcpy(StringPtr d, StringPtr s)
  144. {
  145.     short    i;
  146.  
  147.     i = *s;
  148.     do {
  149.         d[i] = s[i];
  150.     } while (i--);
  151. }
  152.  
  153.  
  154.  
  155. /*****************************************************************************/
  156.  
  157.  
  158.  
  159. /* Convert a c-string to a pascal-string. */
  160.  
  161. void    c2p(char *cptr)
  162. {
  163.     short    len;
  164.  
  165.     BlockMove(cptr, cptr + 1, len = clen(cptr));
  166.     *cptr = len;
  167. }
  168.  
  169.  
  170.  
  171. /*****************************************************************************/
  172.  
  173.  
  174.  
  175. /* Convert a pascal-string to a c-string. */
  176.  
  177. void    p2c(StringPtr cptr)
  178. {
  179.     unsigned char    len;
  180.  
  181.     BlockMove(cptr + 1, cptr, len = *cptr);
  182.     cptr[len] = 0;
  183. }
  184.  
  185.  
  186.  
  187. /*****************************************************************************/
  188. /*****************************************************************************/
  189. /*****************************************************************************/
  190.  
  191.  
  192.  
  193. /* Catenate a single character multiple times onto the designated string. */
  194.  
  195. void    ccatchr(char *cptr, char c, short count)
  196. {
  197.     ccpychr(cptr + clen(cptr), c, count);
  198. }
  199.  
  200.  
  201.  
  202. /*****************************************************************************/
  203.  
  204.  
  205.  
  206. /* Convert the value into text for the base-10 number and catenate it to
  207. ** the designated string.  The value is assumed to be signed.  If you wish
  208. ** to have an unsigned decimal value, call ccatnum with a base of 10. */
  209.  
  210. void    ccatpaddec(char *cptr, char padChr, short minApnd, short maxApnd, long v)
  211. {
  212.     ccatpadnum(cptr + clen(cptr), padChr, minApnd, maxApnd, v, -10);
  213.         /* Catenate value base 10, signed. */
  214. }
  215.  
  216. void    ccatdec(char *cptr, long v)
  217. {
  218.     ccatnum(cptr, v, -10);
  219. }
  220.  
  221.  
  222.  
  223. /*****************************************************************************/
  224.  
  225.  
  226.  
  227. /* Convert the value into text for base-16, format it, and catenate it to the
  228. ** designated string.  ccatnum could be used, since it handles multiple bases,
  229. ** but ccathex allows for additional common formatting and padding of the
  230. ** hex value. */
  231.  
  232. void    ccatpadhex(char *cptr, char padChr, short minApnd, short maxApnd, long v)
  233. {
  234.     char    str[33], *sptr;
  235.     short    len;
  236.  
  237.     cptr += clen(cptr);            /* We're appending, so point to the end of the string. */
  238.     ccpynum(str, v, 16);        /* Generate minimum-digit hex value. */
  239.  
  240.     if ((len = clen(sptr = str)) > maxApnd)
  241.         sptr = str + len - maxApnd;
  242.  
  243.     if ((len = clen(sptr)) < minApnd)
  244.         if (padChr)
  245.             ccatchr(cptr, padChr, (minApnd - len));
  246.                 /* if we have a pad character, and if necessary, pad the string. */
  247.  
  248.     ccat(cptr, sptr);            /* Add the hex digits to the string. */
  249. }
  250.  
  251. void    ccathex(char *cptr, long v)
  252. {
  253.     ccatpadhex(cptr, 0, 0, 8, v);
  254. }
  255.  
  256.  
  257.  
  258. /*****************************************************************************/
  259.  
  260.  
  261.  
  262. /* Convert the value into text for the designated base.  Catenate the text to
  263. ** the designated string. */
  264.  
  265. void    ccatpadnum(char *cptr, char padChr, short minApnd, short maxApnd, long v, short base)
  266. {
  267.     ccpypadnum(cptr + clen(cptr), padChr, minApnd, maxApnd, v, base);
  268. }
  269.  
  270. void    ccatnum(char *cptr, long v, short base)
  271. {
  272.     ccpynum(cptr + clen(cptr), v, base);
  273. }
  274.  
  275.  
  276.  
  277. /*****************************************************************************/
  278.  
  279.  
  280.  
  281. void    ccpychr(char *cptr, char c, short count)
  282. {
  283.     for (;count--; ++cptr) *cptr = c;
  284.     *cptr = 0;
  285. }
  286.  
  287.  
  288.  
  289. /*****************************************************************************/
  290.  
  291.  
  292.  
  293. void    ccpypaddec(char *cptr, char padChr, short minApnd, short maxApnd, long v)
  294. {
  295.     ccpypadnum(cptr, padChr, minApnd, maxApnd, v, -10);
  296. }
  297.  
  298. void    ccpydec(char *cptr, long v)
  299. {
  300.     ccpynum(cptr, v, -10);
  301. }
  302.  
  303.  
  304.  
  305. /*****************************************************************************/
  306.  
  307.  
  308.  
  309. void    ccpypadhex(char *cptr, char padChr, short minApnd, short maxApnd, long v)
  310. {
  311.     cptr[0] = 0;
  312.     ccatpadhex(cptr, padChr, minApnd, maxApnd, v);
  313. }
  314.  
  315. void    ccpyhex(char *cptr, long v)
  316. {
  317.     cptr[0] = 0;
  318.     ccathex(cptr, v);
  319. }
  320.  
  321.  
  322.  
  323. /*****************************************************************************/
  324.  
  325.  
  326.  
  327. void    ccpypadnum(char *cptr, char padChr, short minApnd, short maxApnd, long v, short base)
  328. {
  329.     pcpypadnum((StringPtr)cptr, padChr, minApnd, maxApnd, v, base);
  330.     p2c((StringPtr)cptr);
  331. }
  332.  
  333. void    ccpynum(char *cptr, long v, short base)
  334. {
  335.     pcpynum((StringPtr)cptr, v, base);
  336.     p2c((StringPtr)cptr);
  337. }
  338.  
  339.  
  340.  
  341. /*****************************************************************************/
  342. /*****************************************************************************/
  343. /*****************************************************************************/
  344.  
  345.  
  346.  
  347. long    c2dec(char *cptr, short *charsUsed)
  348. {
  349.     return(c2num(cptr, 10, charsUsed));
  350. }
  351.  
  352.  
  353.  
  354. /*****************************************************************************/
  355.  
  356.  
  357.  
  358. long    c2hex(char *cptr, short *charsUsed)
  359. {
  360.     return(c2num(cptr, 16, charsUsed));
  361. }
  362.  
  363.  
  364.  
  365. /*****************************************************************************/
  366.  
  367.  
  368.  
  369. long    c2num(char *cptr, short base, short *charsUsed)
  370. {
  371.     Boolean    firstDigit;
  372.     short    i, sgn;
  373.     short    c;
  374.     long    val;
  375.  
  376.     sgn = 1;
  377.     for (firstDigit = false, val = 0, i = 0;;) {
  378.         c = cptr[i++];
  379.         if (base == 256) {
  380.             if (!c) break;
  381.             if (c == '\'') {
  382.                 ++i;
  383.                 break;
  384.             }
  385.             val *= base;
  386.             val += c;
  387.             continue;
  388.         }
  389.         if (c == '-') {
  390.             if (firstDigit) break;
  391.             if (sgn == -1)  break;
  392.             sgn = -1;
  393.             continue;
  394.         }
  395.         if (c == '$') {
  396.             if (firstDigit) break;
  397.             base = 16;
  398.             continue;
  399.         }
  400.         if (gHandleChars) {
  401.             if (c == '\'') {
  402.                 if (firstDigit) break;
  403.                 base = 256;
  404.                 continue;
  405.             }
  406.         }
  407.         if (base == 10) {
  408.             if (c < '0') break;
  409.             if (c > '9') break;
  410.         }
  411.         if ((!firstDigit) && (c == ' ')) continue;
  412.         c -= '0';
  413.         if (base == 16) {
  414.             if (c > 16) c -= 7;        /* Make 'A' a 10, etc. */
  415.             if (c > 32) c -= 32;    /* Make lower-case upper-case. */
  416.         }
  417.         if (c < 0) break;
  418.         if (c >= base) break;
  419.         val *= base;
  420.         val += (c * sgn);
  421.         firstDigit = true;
  422.     }
  423.  
  424.     if (charsUsed) *charsUsed = --i;
  425.  
  426.     gBase = base;
  427.     return(val);
  428. }
  429.  
  430.  
  431.  
  432. /*****************************************************************************/
  433.  
  434.  
  435.  
  436. short    GetLastBase(Boolean handleChars)
  437. {
  438.     gHandleChars = handleChars;
  439.     return(gBase);
  440. }
  441.  
  442.  
  443.  
  444. /*****************************************************************************/
  445. /*****************************************************************************/
  446. /*****************************************************************************/
  447.  
  448.  
  449.  
  450. /* Catenate a single character multiple times onto the designated string. */
  451.  
  452. void    pcatchr(StringPtr pptr, char c, short count)
  453. {
  454.     while (count--) pptr[++(pptr[0])] = c;
  455. }
  456.  
  457.  
  458.  
  459. /*****************************************************************************/
  460.  
  461.  
  462.  
  463. void    pcatpaddec(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v)
  464. {
  465.     pcatpadnum(pptr, padChr, minApnd, maxApnd, v, -10);
  466. }
  467.  
  468. void    pcatdec(StringPtr pptr, long v)
  469. {
  470.     pcatnum(pptr, v, -10);
  471. }
  472.  
  473.  
  474.  
  475. /*****************************************************************************/
  476.  
  477.  
  478.  
  479. void    pcatpadhex(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v)
  480. {
  481.     char    str[33];
  482.  
  483.     ccpypadhex(str, padChr, minApnd, maxApnd, v);
  484.     c2p(str);
  485.     pcat(pptr, (StringPtr)str);
  486. }
  487.  
  488. void    pcathex(StringPtr pptr, long v)
  489. {
  490.     pcatpadhex(pptr, 0, 0, 8, v);
  491. }
  492.  
  493.  
  494.  
  495. /*****************************************************************************/
  496.  
  497.  
  498.  
  499. long    pcatnum(StringPtr pptr, long v, short base)
  500. {
  501.     unsigned long    j, vv;
  502.  
  503.     vv = v;
  504.     if (base < 0) {
  505.         base = -base;
  506.         if (v < 0) {
  507.             pptr[++*pptr] = '-';
  508.             vv = -vv;
  509.         }
  510.     }
  511.     j = 0;
  512.     if (vv >= base)
  513.         j = pcatnum(pptr, vv / base, base);
  514.  
  515.     pptr[++*pptr] = "0123456789ABCDEF"[vv - j];
  516.     return(base * vv);
  517. }
  518.  
  519. void    pcatpadnum(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v, short base)
  520. {
  521.     Str32    str;
  522.  
  523.     pcpynum(str, v, base);        /* Generate minimum-digit hex value. */
  524.  
  525.     if (str[0] > maxApnd) str[0] = maxApnd;
  526.  
  527.     if (str[0] < minApnd)
  528.         if (padChr)
  529.             pcatchr(pptr, padChr, (minApnd - str[0]));
  530.                 /* if we have a pad character, and if necessary, pad the string. */
  531.  
  532.     pcat(pptr, str);            /* Add the hex digits to the string. */
  533. }
  534.  
  535.  
  536.  
  537. /*****************************************************************************/
  538.  
  539.  
  540.  
  541. void    pcpychr(StringPtr pptr, char c, short count)
  542. {
  543.     pptr[0] = 0;
  544.     pcatchr(pptr, c, count);
  545. }
  546.  
  547.  
  548.  
  549. /*****************************************************************************/
  550.  
  551.  
  552.  
  553. void    pcpypaddec(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v)
  554. {
  555.     *pptr = 0;
  556.     pcatpaddec(pptr, padChr, minApnd, maxApnd, v);
  557. }
  558.  
  559. void    pcpydec(StringPtr pptr, long v)
  560. {
  561.     *pptr = 0;
  562.     pcatdec(pptr, v);
  563. }
  564.  
  565.  
  566.  
  567. /*****************************************************************************/
  568.  
  569.  
  570.  
  571. void    pcpypadnum(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v, short base)
  572. {
  573.     *pptr = 0;
  574.     pcatpadnum(pptr, padChr, minApnd, maxApnd, v, base);
  575. }
  576.  
  577. void    pcpynum(StringPtr pptr, long v, short base)
  578. {
  579.     *pptr = 0;
  580.     pcatnum(pptr, v, base);
  581. }
  582.  
  583.  
  584.  
  585. /*****************************************************************************/
  586.  
  587.  
  588.  
  589. void    pcpypadhex(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v)
  590. {
  591.     *pptr = 0;
  592.     pcatpadhex(pptr, padChr, minApnd, maxApnd, v);
  593. }
  594.  
  595. void    pcpyhex(StringPtr pptr, long v)
  596. {
  597.     pcpypadhex(pptr, 0, 0, 8, v);
  598. }
  599.  
  600.  
  601.  
  602. /*****************************************************************************/
  603.  
  604.  
  605.  
  606. long    p2dec(StringPtr pptr, short *charsUsed)
  607. {
  608.     return(p2num(pptr, 10, charsUsed));
  609. }
  610.  
  611.  
  612.  
  613. /*****************************************************************************/
  614.  
  615.  
  616.  
  617. long    p2hex(StringPtr pptr, short *charsUsed)
  618. {
  619.     return(p2num(pptr, 16, charsUsed));
  620. }
  621.  
  622.  
  623.  
  624. /*****************************************************************************/
  625.  
  626.  
  627.  
  628. long    p2num(StringPtr pptr, short base, short *charsUsed)
  629. {
  630.     long    val;
  631.  
  632.     p2c(pptr);
  633.     val = c2num((char *)pptr, base, charsUsed);
  634.     c2p((char *)pptr);
  635.     return(val);
  636. }
  637.  
  638.  
  639.  
  640. /*****************************************************************************/
  641. /*****************************************************************************/
  642. /*****************************************************************************/
  643.  
  644.  
  645.  
  646. short    GetHexByte(char *cptr)
  647. {
  648.     short    val, i, chr;
  649.  
  650.     for (val = 0, i = 0; i < 2; ++i) {
  651.         chr = cptr[i];
  652.         if (chr == '=') return(cptr[++i]);
  653.         if (chr == '≈') {
  654.             chr = cptr[++i];
  655.             if ((chr >= 'a') && (chr <= 'z')) chr -= 32;
  656.             return(chr);
  657.         }
  658.         if (chr > 'F')
  659.             chr -= 0x20;
  660.         if (chr > '9')
  661.             chr -= ('A' - '9' - 1);
  662.         val = (val << 4) + chr - '0';
  663.     }
  664.     return(val);
  665. }
  666.  
  667.  
  668.  
  669. /*****************************************************************************/
  670.  
  671.  
  672.  
  673. Boolean    EqualHandle(void *h1, void *h2)
  674. {
  675.     long    s1, s2;
  676.     Ptr        p1, p2;
  677.  
  678.     if ((h1) && (!h2)) return(false);
  679.     if ((h2) && (!h1)) return(false);
  680.     if ((s1 = GetHandleSize(h1)) != (s2 = GetHandleSize(h2))) return(false);
  681.  
  682.     p1 = *(Handle)h1;
  683.     p2 = *(Handle)h2;
  684.     for (s1 = 0; s1 < s2; ++s1)
  685.         if (p1[s1] != p2[s1]) return(false);
  686.         
  687.     return(true);
  688. }
  689.  
  690.  
  691.  
  692. /*****************************************************************************/
  693.  
  694.  
  695.  
  696. Boolean    EqualData(void *v1, void *v2, long size)
  697. {
  698.     Ptr        p1, p2;
  699.     long    ii;
  700.  
  701.     if ((v1) && (!v2)) return(false);
  702.     if ((v2) && (!v1)) return(false);
  703.  
  704.     p1 = (Ptr)v1;
  705.     p2 = (Ptr)v2;
  706.     for (ii = 0; ii < size; ++ii)
  707.         if (p1[ii] != p2[ii]) return(false);
  708.         
  709.     return(true);
  710. }
  711.  
  712.  
  713.  
  714. /*****************************************************************************/
  715.  
  716.  
  717.  
  718. void    SetMem(void *vptr, unsigned char c, unsigned long len)
  719. {
  720.     Ptr    ptr;
  721.  
  722.     ptr = (Ptr)vptr;
  723.     while (len--) *ptr++ = c;
  724. }
  725.  
  726.  
  727.  
  728. /*****************************************************************************/
  729.  
  730.  
  731.  
  732. OSErr    HInsert(Handle hh, long offset, void *dataptr, long delta);
  733. OSErr    HInsert(Handle hh, long offset, void *dataptr, long delta)
  734. {
  735.     long    dataSize;
  736.     char    *cptr;
  737.     OSErr    err;
  738.  
  739.     dataSize = GetHandleSize(hh);
  740.  
  741.     if (!(delta & 0x80000000L)) {
  742.         SetHandleSize(hh, dataSize + delta);
  743.         err = MemError();
  744.         if (err) return(err);
  745.     }
  746.     else {
  747.         offset -= delta;
  748.             /* We are removing what we are pointing/offset at, so the block that is to be moved is
  749.             ** after the data being removed at the offset.  The size of the data being removed is
  750.             ** i-delta, so therefore subtract this negative number from offset to skip past data. */
  751.     }
  752.  
  753.     cptr = (*(char **)hh) + offset;
  754.     BlockMove(cptr, cptr + delta, dataSize - offset);
  755.  
  756.     if (delta & 0x80000000L) {
  757.         SetHandleSize(hh, dataSize + delta);
  758.             /* Delta is negative -- we are deleting data.  dataptr is unused. */
  759.     }
  760.     else {
  761.         cptr = (*(char **)hh) + offset;
  762.         BlockMove(dataptr, cptr, delta);
  763.             /* Delta is positive -- we are adding data pointed at by dataptr. */
  764.     }
  765.  
  766.     return(noErr);
  767. }
  768.  
  769.  
  770.  
  771.